#include "server_initial.h"
#include "server_pthread.h"

//监听观战者是否要求退出或掉线
void epoll_watchers(room* watcher)
{
    while (1)
    {
        //等待事件发生
        struct epoll_event evt[10];
        int size = epoll_wait(watcher->epwatch, evt, 10, -1);
        if(size < 0)
        {
            perror("wait error");
            continue;
        }
        for (int i = 0; i < size; i++)
        {
             int ret /*=  看传过来的是客户掉线还是要求退出 */;
            epoll_watcher_del(watcher->epwatch, &evt[i]);
            if(ret == -1)
            {
                close(evt[i].data.fd);
                continue;
            }
            vector<playdata*>::iterator temp ;
            for ( temp = watcher->watcher.begin(); temp != watcher->watcher.end(); temp++)
            {
                if (evt[i].data.fd == (*temp)->cilentfd)
                {
                    // thread chose_oparetor(/* 等待用户选择 */, *temp);
                    break;
                }
            }   
        }   
    } 
}

//添加在游戏界面观战的客户端的套接字
void room::add_watcher(playdata* arg)
{
    watcher.insert(watcher.end(),arg);
    int ret = epoll_watcher_add(epwatch, arg->cilentfd);
}

//删除在游戏界面观战的客户端的套接字
bool room::del_watcher(playdata* arg)
{
    //暂存用户的数据
    vector<playdata*>::iterator it;
    for (it = watcher.begin(); it != watcher.end(); it++)
    {
        if (arg->cilentfd == (*it)->cilentfd)
        {

            watcher.erase(it);
            break;
        }
    }
    if (it == watcher.end())
    {
        cout << "未找到相应标识符" << endl;
        return false;
    }
    return true;
}

//为监听观众创建线程
void room::create_pthread()
{
    thread watch(epoll_watchers,this);
}

// 向参数中的套接字发送对局信息
bool room::send_data(playdata* arg)
{
    cout << "yes" << endl;
    return 0;
}

//监听棋手的套接字描述符
void room::monitor()
{
    int epoll_fd = epoll_create(2);
    if (-1 == epoll_fd)
    {
        cout << "创建epoll描述符失败" << endl;
        return ;
    }
    struct epoll_event event;
    event.events = EPOLLIN;
    event.data.fd = host->cilentfd;
    int eret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, host->cilentfd, &event);
    if(eret<0)
    {
        perror("add error");
        return ;
    }
    event.data.fd = gec->cilentfd;
    eret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, gec->cilentfd, &event);
    if (-1 == eret)
    {
        cout << "gec add error" << endl;
        return ;
    }
    create_pthread();
    int flag = 0;
    while(1)
    {
        if (flag != 0)
        {
            
            break;
        }
        
        send_data(host);
        send_data(gec);
        // int host_
        for ( vector<playdata*>::iterator it = watcher.begin(); it != watcher.end() ; it++)
        {
            send_data(*it);
        }
        
        //等待事件发生
        struct epoll_event evt[10];
        int size = epoll_wait(epoll_fd, evt, 10, -1);
        if(size < 0)
        {
            perror("wait error");
            continue;
        }

        for(int i=0; i<size; i++)
        {
            //判断是否是监听套接字sockfd
            if(evt[i].data.fd == host->cilentfd)
            {
                //对传过来的数据进行处理

            }
            else
            {
                
            }
        }
    }
    Data &temp = Data::get_Data();
    temp.room_num--;
    game_over();
}

//将所有的房间编号放入字符串中
void Data::traverse(char* room_id)
{
    sprintf(room_id,"%d",room_num);
}

//遍历房间,找到房间返回房间地址，未找到返回nullptr
room* Data::traverse(int room_id)
{
    if (room_id == 0)
    {
        for ( vector<room*>::iterator it = vol.begin(); it != vol.end(); it++)
        {
            if ((*it)->gec == nullptr)
            {
                return *it;
            }
        }
    }
    else
    {
        for ( vector<room*>::iterator it = vol.begin(); it != vol.end(); it++)
        {
            if ((*it)->id == room_id)
            {
                return *it;
            }
        }
    }
    return nullptr;
}

//创建房间
void Data::create_room(playdata * host)
{
    latch.lock();
    vol.insert(vol.end(),new room(host, ++room_num));
    latch.unlock();
}

//创建并返回被监听的套接字
int sock_initial()
{
    int sersock = socket(AF_INET, SOCK_STREAM, 0);
    if (sersock == -1)
    {
        cout << "服务器套接字创建失败" << endl;
        return -1;
    }
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(9999);
    addr.sin_addr.s_addr = INADDR_ANY; //192.168.13.1
    int ret =  bind(sersock, (struct sockaddr*)(&addr),sizeof(addr));
    if (-1 == ret)
    {
        cout << "服务器套接字绑定失败" << endl;
        return -1;
    }
    ret = listen(sersock, 10);
    if (ret == -1)
    {
        cout << "监听失败" << endl;
        return -1;
    }
    
    return sersock;
}



